{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "d7cb7909",
   "metadata": {},
   "source": [
    "# PyTorch – 深度学习全栈工程师进阶案例实战（第十期）第8课书面作业\n",
    "学号：115539\n",
    "\n",
    "**作业内容：**    \n",
    "认真学习视频知识和阅读补充材料后，请说出FasterRCNN相比于普通RCNN最大的三个区别。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6983d57d",
   "metadata": {},
   "source": [
    "**答：**  \n",
    "阅读了三篇论文，总结如下："
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4467b928",
   "metadata": {},
   "source": [
    "### 1. R-CNN论文解读"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "60b5b3d2",
   "metadata": {},
   "source": [
    "该论文提出了一种称之为R-CNN（Regions with CNN features ）的神经网络模型，在物体检测领域相比之间低维特性空间操作的传统模型而言，检测性能提升30%以上。作者认为该方法结合了两个关键点：\n",
    "\n",
    "1. 将大容量卷积神经网络 (CNN) 应用于自下而上的检测区域提议（region proposals  ），以便定位和分割对象；  \n",
    "2. 当训练模型标识数据稀缺时，采用预训练模型为基础加以特定领域的微调，会产生显着性能提升。\n",
    "\n",
    "![paper02-1](https://gitee.com/dotzhen/cloud-notes/raw/master/paper02-1.png)\n",
    "\n",
    "论文中的模型如上图所示：\n",
    "\n",
    "* 首先要采用传统的（非深度学习的）方法来产生区域提议（region proposals ），本论文采用的方法是选择性搜索（selective search ）方法。针对一个输入图片产生大约2K个区域提议；\n",
    "* 因为得到的区域揭底尺寸大小不一，因此在进行后面统一处理时，需要将之绽放到统一尺寸，这里叫warped region；\n",
    "* 将统一尺寸后的warped region输入一个深度卷积网络，得到一些CNN feature maps。\n",
    "* 将上面得到的特征（CNN feature maps）用一个支持向量机进行分类，确定这个region proposal对应的分类是哪一个。\n",
    "\n",
    "\n",
    "\n",
    "对于区域提议，论文中还提到了对其进行改善的方法，即把它当成一个回归问题来处理。即训练一个回归器，将由选择性搜索得到的区域提议输入这个回归器得到改善后的区域提议，再进行后续处理。这个回归器如下训练：\n",
    "\n",
    "* 给出如下的训练集：$\\{P,G\\}$, $P$表示选择性搜索得到的区域提议（这里做为回归器训练的样本中的自变量），$P=(P_x,P_y,P_w,P_h)$，$G=(G_x,G_y,G_w,G_h)$表示ground-truth，即训练样本的标签。\n",
    "\n",
    "* 我们将训练4个函数（也就是4个回归器），$d_x(P),d_y(P),d_w(P),d_h(P)$\n",
    "\n",
    "* 预测的区域提议将通过如下公式得到：\n",
    "  $$\n",
    "  \\begin{align*}\n",
    "  \\hat{G}_x&=P_xd_x(P)+P_x \\\\\n",
    "  \\hat{G}_y&=P_yd_y(P)+P_y \\\\\n",
    "  \\hat{G}_w&=P_w\\exp(d_w(P)) \\\\\n",
    "  \\hat{G}_h&=P_h\\exp(d_h(P)) \\\\\n",
    "  \\end{align*}\n",
    "  $$\n",
    "\n",
    "* 我们用$d_*(P)$表示上面四个回归函数，将被建模为区域提议P在CNN网络中$Pool_5$层输出的线性模型，我们记这一模型为：$d_*(P) = W_*^T\\phi_5(P)$。\n",
    "\n",
    "* 这些回归器的求解就是要解算出上面公式中的权值($W_*^T$)在如下目标函数中达到最小，这个目标函数显然是个岭回归问题：\n",
    "  $$\n",
    "  W_*=\\arg \\min_{\\hat{W_*}}\\sum_{i=1}^N (t_*^i-\\hat{W}_*^T\\phi_5(P^i))^2+\\lambda||\\hat{W}_*||^2\n",
    "  $$\n",
    "  上式中$t_*$是回归目标值，定义如下：\n",
    "  $$\n",
    "  \\begin{align*}\n",
    "  t_x&=(G_x-P_x)/P_w \\\\\n",
    "  t_y&=(G_y-P_y)/P_h \\\\\n",
    "  t_w&=\\log(G_w/P_w) \\\\\n",
    "  t_h&=\\log(G_h/P_h) \\\\\n",
    "  \\end{align*}\n",
    "  $$\n",
    "\n",
    "* 用线性回归方法得到$W_*$，得到$d_*(P)$，得到$\\hat{G}_*$，即改善后的区域提议。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "52197f3d",
   "metadata": {},
   "source": [
    "### 2. Fast R-CNN论文解读"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "421be39e",
   "metadata": {},
   "source": [
    "这篇论文是R-CNN原作者在R-CNN基础上做的改进版本，新版本的模型称之为Fast R-CNN，该模型显著提升了模型训练及测试速度，并同时提升了准确度。Fast R-CNN相比R-CNN在训练上快9倍（用VGG16），在测试上快213倍。\n",
    "\n",
    "首先，论文作者自己总结了一下R-CNN缺点：\n",
    "\n",
    "1. 训练过程是多阶段的。准确的说是三阶段：\n",
    "   1. 第一阶段：是针对目标检测区域对ConvNet网络进行参数fine-tune；\n",
    "   2. 第二阶段：SVM模型作为分类器的训练；\n",
    "   3. 第三阶段：对矩形目标框的回归训练；\n",
    "2. 训练在时间和空间上都不优。时间上是训练时间漫长，空间上是需要暂存大量的中间数据。\n",
    "3. 测试时预测时间慢。\n",
    "\n",
    "我们可以看看，在这篇论文中作者是如何改进上面的问题的。下面是模型框架：\n",
    "\n",
    "![paper03-1](https://gitee.com/dotzhen/cloud-notes/raw/master/paper03-1.png)\n",
    "\n",
    "* 模型的输入还是图片+region proposals，proposals还是用selective search得来的。\n",
    "\n",
    "* 模型重大的改进是将目标边界框（这里的bbox，也就是region proposal）的回归与这块区域图像的目标分类器整合到了一个模型中，同时分类器直接使用深度ConvNet来做，而不是像R-CNN中用ConvNet提取特征，再输入一个SVM中做分类。\n",
    "\n",
    "* 图片输入模型后，会先整体用尝试ConvNet做处理，输出特征图，然后根据不同的目标边界框做ROI pooling操作，这个ROI，即region of interest，就是在整体特征图中“抠”出指定目标边界框那部分特征图出来，并将之处理成统一大小方便后续处理。这样深度网络提升特征的动作只需要全局计算一次，针对不同region proposals的ROI Pooling只是在这个全局特征图中截取部分特征图，这样的操作明显减少了很多计算量。\n",
    "\n",
    "* ROI pooling后的数据会有两个不同的输出，一个是进行分类处理，一个是进行目标边框的回归。这里设计了一个联合损失函数，将分类预测结果与目标边框结果统一纳入损失函数：\n",
    "  $$\n",
    "  L(p,u,t^u,v)=L_{cls}(p,u)+\\lambda[u\\ge1]L_{loc}(t^u,v)\n",
    "  $$\n",
    "  上式中$L$为联合损失函数，$p$表示分类预测概率结果，$u$是标签，即真实分类情况，$t^u$表示在$u$分类下的回归得到的目标边框（有4个分量，即$x,y,w,h$），$v$表示目标边框的真实值。$[u\\ge1]$表示$u\\ge1$时为1否则为0，这个也很好理解，只有是正例时，目标边框才有意义。\n",
    "\n",
    "  分类损失定义如下（对数损失函数）：\n",
    "  $$\n",
    "  L_{cls}(p,u)=-\\log p_u\n",
    "  $$\n",
    "  目标边框损失函数定义如下：\n",
    "  $$\n",
    "  L_{loc}(t^u,v)=\\sum_{i \\in \\{x,y,w,h\\}}\\operatorname{smooth}_{L1}(t_i^u-v_i) \\\\\n",
    "  \\operatorname{smooth}_{L1}(x)=\n",
    "  \\begin{cases}\n",
    "  0.5x^2,\\quad if\\; |x| \\lt 1 \\\\[2ex]\n",
    "  |x|-0.5, \\quad otherwise,\n",
    "  \\end{cases}\n",
    "  $$\n",
    "\n",
    "* 经过上面的处理巧妙地将回归与分类处理融合到了一个模型中通过统一联合损失函数来约束并优化网络参数。较好地解决了R-CNN原有问题。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b1f9ea43",
   "metadata": {},
   "source": [
    "### 3. Faster R-CNN论文解读"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "39520640",
   "metadata": {},
   "source": [
    "这篇论文是目标检测领域内的一次改进，是对Fast R-CNN网络的进一步改进。在此之前的将深度神经网络应用到目标检测领域中都需要用非神经网络方法得到region proposals即目标区域边框作为输入的一部分，这个过程导致了性能上的一个瓶颈。在这篇论文中给出了一个RPN网络（region proposal network），这个网络可以替代R-CNN/Fast R-CNN中使用的selective search方法，得到region proposals，同时这RPN也是一个全卷积网络，并且它可以与Fast R-CNN融合到一个网络中，同时训练。这样整体网络的输入只需要输入图片即可，RPN与Fast R-CNN共享全局的特征图，并可以端到端同时训练，也就意味着得到region proposals不需要额外的开销，或者说开销很小。这个方法相比Fast R-CNN速度与性能上都有提升。\n",
    "\n",
    "Ross Girshick在2013年提出了R-CNN（这里还是在伯克利大学），并在2015年4月改进了它提出了Fast R-CNN（这里已经在微软了），2015年6月Shaoqing Ren, Kaiming He（这是个大神），Ross Girshick等提出的这篇Faster R-CNN又是对Fast R-CNN的改进，只不过此时Ross Girshick是第三作者了。\n",
    "\n",
    "本次重大的改进，主要是针对作为输入region proposals了，也就是不要selective search了。这次直接输入图片，得到目标物体的边界框，以及这个边界框内的物体分类是什么。\n",
    "\n",
    "我们怎么做的呢？\n",
    "\n",
    "<img src=\"https://gitee.com/dotzhen/cloud-notes/raw/master/paper04-1.png\" alt=\"paper04-1\" style=\"zoom: 33%;\" />\n",
    "\n",
    "上图是Faster R-CNN的模型图，我们可以看到：\n",
    "\n",
    "1. 模型运作是这样一个过程：\n",
    "\n",
    "   1. 图片输入，通过深度卷积层得到feature maps;\n",
    "   2. RPN根据feature maps计算得到很多region proposals以及每个region proposal中是否有物体的概率（不是分类，只是判定是否有物体）\n",
    "   3. 分类器（就是最上面那一层，或者叫Fast R-CNN）的输入有两个，一个是feature maps，另一个是region proposals+objectness probability，分类器输出，目标边框以及目标分类（概率值，softmax输出）。\n",
    "\n",
    "2. 可以看出上面的模型中没有了selective search，模型自己来学习需要关注的region proposals是啥？所以论文中将RPN也称之为“attention”。\n",
    "\n",
    "3. 图片中的深度特征提取是通过深度卷积网络，只提取了一次，RPN直接用feature maps，分类器也直接用feature maps, 只是分类器使用时，需要通过RoI pooling操作，这个操作相当于只在feature maps中提取region proposals指定的那个矩形对应的feature maps。这样就减少了计算量。\n",
    "\n",
    "4. RPN是如何得到不同的目标边框（region proposal）的呢？\n",
    "\n",
    "   ![paper04-2](https://gitee.com/dotzhen/cloud-notes/raw/master/paper04-2.png)\n",
    "\n",
    "   1. RPN使用featue maps作为输入；\n",
    "   2. RPN使用3*3的滑动窗口在feature maps上滑过，滑动窗口的中心就是论文中所说的锚点（anchor），根据锚点为中心产生不同缩放比例和纵横比例的矩形区域，在本论文中选择3种不同缩放比例和3种不同纵横比例，这就意味着每个锚点对应9个不同矩形区域，假设feature maps的尺寸是$W\\times H$,那么总共有$9\\times W\\times H$个region proposals。\n",
    "   3. 上述这些不同的区域将被映射到更低维度的特性上，并进一步并传入两个全连接层（可以用卷积网络实现，好处是共享权值），一个用来回归目标边框，一个用来确定是否有物体存在的概率。\n",
    "\n",
    "5. 总体网络的损失函数设计如下：\n",
    "   $$\n",
    "   L(\\{p_i\\},\\{t_i\\})=\\frac{1}{N_{cls}}\\sum_iL_{cls}(p_i,p_i^*)+\\lambda\\frac{1}{N_{reg}}\\sum_ip_i^*L_{reg}(t_i,t_i^*)\n",
    "   $$\n",
    "   上式中$i$表示在训练过程中一个mini-batch中某个锚点的编号。$p_i$表示第$i$个锚点是否是物体的预测的概率，$p_i^*$表示第$i$个锚点是否是物体的真实值（ground truth）。$t_i$表示对于对应第$i$个锚点的预测的物体矩形边框（包含4个分量，即$x,y,w,h$，因此$t_i$是个向量），$t_i^*$则表示对应第$i$个锚点的物体真实矩形边框。$L_{cls}$表示分类器的损失函数，这里分类器的损失函数是采用对数损失函数。$L_{reg}$表示物体矩形边框的回归损失函数，这里使用的损失函数与Fast R-CNN中的一样，即：\n",
    "   $$\n",
    "   \\operatorname{smooth}_{L1}(x)=\n",
    "   \\begin{cases}\n",
    "   0.5x^2,\\quad if\\; |x| \\lt 1 \\\\[2ex]\n",
    "   |x|-0.5, \\quad otherwise\n",
    "   \\end{cases}\n",
    "   $$\n",
    "   在整体损失函数中，$p_i^*L_{reg}(t_i,t_i^*)$前面乘以了$p_i^*$的目的是：这一损失函数项只在锚点确实存在物体时激活。这一技术同样在Fast R-CNN中使用了。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2c88aa6c",
   "metadata": {},
   "source": [
    "### 4. 三种网络对比"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0e6a213b",
   "metadata": {},
   "source": [
    "1. Faster R-CNN相比R-CNN:\n",
    "   1. 将原来三段式的训练（有3个模型，分别是：第1，特征提取的网络；第2，SVM分类器训练；第3，矩形目标框的回归训练）简化为一段式训练（Fast-RCNN+RPN是一个整体网络，是一次训练）；\n",
    "   1. 三段式训练简化为一段式训练后，时间节省了这是明显的，同时空间也节省了，原来R-CNN还需要缓存大量的中间数据。\n",
    "   1. 预测的时间加快了，没有了selective search，没有了SVM分类过程，利用了feature maps的结果。\n",
    "\n",
    "1. Faster R-CNN相比Fast R-CNN:\n",
    "   1. 取消了selective search过程，直接由网络推断出bbox。产生bbox推断的RPN网络和分类网络融合，一起训练，提升了效率。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "35c9e0a5",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
